data Tree a = EmptyTree | Node a (Tree a) (Tree a)
list2tree2 :: [a] -> Tree a
list2tree2 xs = ?
Написать функцию, строящую сбалансированное дерево в один проход
Это не дерево поиска!
list2tree2 xs = fst (build (length xs) xs)
build :: Int -> [a] -> (Tree a, [a])
build 0 xs = (EmptyTree, xs)
build 1 (x:xs) = (Node x EmptyTree EmptyTree, xs)
build n (x:xs) = (Node x u v, xs'')
where
m = div (n-1) 2
(u, xs') = build m xs
(v, xs'') = build (n-1-m) xs'
Разные аксиомы
© wikipedia
когда домен = кодомен, это – эндоморфизм
классический пример: категория Set
объекты категории Set — это всевозможные множества, а морфизмы — это функции между этими множествами.
объекты — это типы данных, возможные в языке Haskell: Int, [], Tree, a, b
а морфизмы — функции языка Haskell: Int → Int, (a → b) → a → b, Tree → Int
class Category (~>) where
(.) :: (a ~> b) -> (b ~> c) -> (a ~> c)
id :: a ~> a
законы:
функтор F — тип отображений между категориями, позволяет сохранить структуру категорий при создании между ними различных связей
другими словами, это гомоморфизм между двумя категориями
При этом функтор отображает объекты первой категории в объекты второй, а морфизмы первой — в морфизмы второй категории. К тому же накладываются определённые ограничения — аксиомы.
Если функтор отображает категорию саму в себя, такой функтор называется эндофунктором.
Любой конструктор выполняет преобразования
[]: a -> [a]
Maybe: b -> Maybe b: Just b | Nothing
data C c = …
C: c → C c
Если теперь такое отображение объектов (конструктор типов C с одним параметром) дополнить отображением морфизмов, то получим функтор, действующий из Hask в Hask, эндофунктор на категории Hask.
class Functor f where
fmap :: (a -> b) -> f a -> f b
∀ f, g : fmap f . fmap g = fmap (f . g)
fmap id = id id x = x fmap id x = id x
> map (+1) [1,2,3,4,5]
[2,3,4,5,6]
instance Functor [] where
fmap = map
fmap id = id
fmap (g . h) = fmap g . fmap h
(read . show $ 4)::Int
fmap (show . (+2)) [1..4]
(fmap show . fmap (+2)) [1..4]
instance Functor Tree where
fmap g EmptyTree = EmptyTree
fmap g (Node a l r) = Node (g a) (fmap g l) (fmap g r)
fmap length (list2tree2 ["goodbye", "cruel", "world"])
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
fmap show . fmap (+2) $ Just 4
fmap (show . (+2)) $ Just 4
fmap show . fmap (+2) $ Nothing
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
Доказать, что
fmap (f . g) = fmap f . fmap g
fmap (f . g) F = fmap f (fmap g F)
:t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
fmap :: Functor f => (a -> b) -> (f a -> f b)
.:t fmap (show . (1+))
... :: (Functor f, Num b, Show b) => f b -> f String
.:t fmap (replicate 3)
... :: Functor f => f a -> f [a]
fmap (replicate 3) [1,2,3]
fmap (replicate 3) $ Just 2
fmap (replicate 3) Just 2 ?
let a = fmap (*) [1,2,3,4]
.:t a
a :: Num a => [a -> a]
fmap (\f -> f 9) a
[9,18,27,36]
import Control.Applicative
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
instance Applicative Maybe where
pure = Just
Nothing <*> _ = Nothing
(Just f) <*> something = fmap f something
Just (+3) <*> Just 9
pure (+3) <*> Just 9
Just (++"hahah") <*> Nothing
Nothing <*> Just "woot"
pure (+) <*> Just 3 <*> Just 5
pure (\x y z -> x + y + z) <*> Just 3 <*> Just 5 <*> Just 2
(<$>) :: (Functor f) => (a -> b) -> f a -> f b
f <$> x = fmap f x
pure (\x y z -> x + y + z) <*> Just 3 <*> Just 5 <*> Just 2
(\x y z -> x + y + z) <$> Just 3 <*> Just 5 <*> Just 2
instance Applicative [] where
pure x = [x]
fs <*> xs = [f x | f <- fs, x <- xs]
[(*0),(+100),(^2)] <*> [1,2,3]
[0,0,0,101,102,103,1,4,9]
[(+),(*)] <*> [1,2] <*> [3,4]
[4,5,5,6,3,4,6,8]
[ x*y | x <- [2,5,10], y <- [8,10,11]]
[16,20,22,40,50,55,80,100,110]
(*) <$> [2,5,10] <*> [8,10,11]
[16,20,22,40,50,55,80,100,110]
newtype ZipList a = ZipList { getZipList :: [a] }
instance Applicative ZipList where
pure x = ZipList (repeat x)
ZipList fs <*> ZipList xs =
ZipList (zipWith (\f x -> f x) fs xs)
getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [1,1,1]
[2,3,4]
getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [1,1..]
[2,3,4]
getZipList $ (,,) <$> ZipList "dog"
<*> ZipList "cat" <*> ZipList "rat"
[('d','c','r'),('o','a','a'),('g','t','t')]
liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = f <$> a <*> b
liftA2 (:) (Just 1) (Just [2])
liftA3 (,,) [1] [2] [3]
sequenceA :: (Applicative f) => [f a] -> f [a]
sequenceA [] = pure []
sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
sequenceA [Just 3, Just 2, Just 1]
sequenceA [Just 3, Nothing, Just 1]
sequenceA [(+3),(+2),(+1)] 3
sequenceA [[1,2,3],[4,5,6]]
sequenceA [[1,2,3],[4,5,6],[3,4,4],[]]
-- sequenceA через свертку !
sequenceA' :: (Applicative f) => [f a] -> f [a]
sequenceA' = foldr (liftA2 (:)) (pure [])
and $ map (\f -> f 7) [(>4),(<10),odd]
True
and $ sequenceA [(>4),(<10),odd] 7
True
.:t getLine
getLine :: IO String
sequenceA [getLine, getLine, getLine]
pure f <*> x = fmap f x
pure id <*> v = v
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
pure f <*> pure x = pure (f x)